<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      function Animal(name) {
        this.name = name;
        this.getName = function () {
          return this.name;
        };
      }
      Animal.prototype.say = function () {
        console.log("hello" + this.name);
      };

      function Dog(name) {
        // 继承父类构造函数中的属性和方法
        Animal.call(this, name);
        this.age = 23;
      }
      // 前两种继承的组合
      // 继承 父类原型上的属性和方法
      // 解决调用 两次构造函数的问题

      // Dog.prototype = new Animal();
      // Dog.prototype.constructor = Dog;

      Dog.prototype = Object.create(Animal.prototype);
      Dog.prototype.constructor = Dog;
      // 甚至还可以在这个原型上定义 dog 的方法 不会影响父类

      var dog1 = new Dog("张三");
      console.log(dog1);

      // Object.create(对象);(原型式继承)  可以实现对象的 继承 (创建一个新对象，使用现有的对象来提供新创建的对象的__proto__。) (对象的浅拷贝) 多个实例的引用类型属性指向相同的内存，存在篡改的可能
      // 使用原型式继承可以获得一份目标对象的浅拷贝，然后利用这个浅拷贝的能力再进行增强，添加一些方法，这样的继承方式就叫作寄生式继承。

      // 寄生组合式继承 是所有继承方式里面相对最优的继承方式
      // 最好属性定义在构造函数中,方法定义在原型对象中
    </script>
  </body>
</html>
